using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input.Touch;

namespace Elementum
{
    public abstract class VisibleObject : Constant
    {


        public delegate void TouchActionHandler(VisibleObject owner,TouchLocationState state);
        public event TouchActionHandler TouchStateAction;
        public event TouchActionHandler ActionEvent;

        public delegate void IsTouchChangeEventHandler(bool touched);
        public event IsTouchChangeEventHandler IsTouchChangeEvent;

        public delegate void ActionHandler();
        public event ActionHandler TouchHoldAction;

       public float _baseAlpha = 1f;
        public VisibleObject _parents;
        public List<VisibleObject> _children=new List<VisibleObject>();

        protected Animation _animation;
        protected Texture2D _texture;
        protected Matrix _transform;

        public ModifierContain ModifierContainer { get; set; }

        public virtual void OnDraw(SpriteBatch spriteBatch, Matrix transform) {
            _transform = transform;
            for (int i = _children.Count() - 1; i >= 0; i--)
                _children[i].OnDraw(spriteBatch,transform);
        }
        public virtual void OnDraw(SpriteBatch spriteBatch)
        {
            for (int i = _children.Count() - 1; i >= 0; i--)
                _children[i].OnDraw(spriteBatch);
        }
        public virtual void Update(int delta) {
            for (int i = _children.Count() - 1; i >= 0; i--)
                _children[i].Update(delta);

            if (ModifierContainer != null)
                ModifierContainer.Update();
            if (CurrentAnimation != null)
            {
                CurrentAnimation.Scale = Scale;
                CurrentAnimation.Rotation = Rotation;
                CurrentAnimation.Alpha = Alpha;
                CurrentAnimation.Update(delta);
            }
        }
        public virtual void Restart()
        {
           
        }

        public int ActionEventCount {
            get
            {
                if (ActionEvent == null)
                    return 0;
                return ActionEvent.GetInvocationList().Length;
            }
        }

        public float Alpha { get; set; }

        protected bool _isTouched;

        public virtual bool IsTouched
        {
            get { return _isTouched; }
            set {
                if (_isTouched != value && IsTouchChangeEvent!=null)
                    IsTouchChangeEvent(value);
                _isTouched = value;
            }
        }

        

        public virtual bool InView
        {
            get
            {
                if (_transform == null)
                    throw new Exception("null transform matrix!");

                Vector2 pos = Vector2.Transform(Position, _transform);
                if (pos.X > -80 && pos.X < 800 + 80 && pos.Y > -80 && pos.Y < 480 + 80)
                    return true;
                return false;
            }
        }

        public virtual Vector2 Position { get; set; }

        protected virtual bool IsTouch(TouchCollection touch,out TouchLocationState state )
        {
            IsTouched = false;
            state = TouchLocationState.Invalid;
            if (this.CurrentAnimation == null)
                return false;
            foreach (TouchLocation touchPointEvent in touch)
            {  
                if (CurrentAnimation.IsInView(touchPointEvent.Position))
                {
                    IsTouched = true;
                    state = touchPointEvent.State;
                    return true;
                }
            }
            return false;
        }

        public virtual Animation CurrentAnimation
        {
            get { return _animation; }
            set { _animation = value; }
        }

        public virtual float Rotation { get; set; }

        public float Scale { get; set; }

        public virtual void AddChild(VisibleObject visibleObject) {
            _children.Add(visibleObject);
            visibleObject._parents = this;
        }

        public virtual bool DoTouch(TouchCollection touch)
        {
            bool isChildenTouch=false;
            for (int i = _children.Count() - 1; i >= 0; i--)
                isChildenTouch = _children[i].DoTouch(touch) || isChildenTouch;
             TouchLocationState state;
            if (IsTouch(touch,out state))
            {
                if (TouchStateAction != null)
                    TouchStateAction( this,state);
                if (TouchHoldAction != null)
                    TouchHoldAction();
            }
            return IsTouch(touch, out state) || isChildenTouch;
        }

        protected virtual bool IsTouch(TouchLocationState state)
        {
            IsTouched = false;
            if (this.CurrentAnimation == null)
                return false;
                if (CurrentAnimation.IsInView(Position))
                {
                    IsTouched = true;
                    return true;
                }
            return true;
        }







        public virtual void Action(VisibleObject owner, TouchLocationState state)
        {
            if (ActionEvent != null)
                ActionEvent(this,state);
        }

        public virtual void Dispose() { } 
    }
}
